import { message as msg } from 'antd'
import type {
  AxiosError,
  AxiosInstance,
  AxiosRequestConfig,
  AxiosResponse,
} from 'axios'
import axios from 'axios'
import router from '../router'

/* ====== 1. 创建实例 ====== */
const instance: AxiosInstance = axios.create({
  timeout: 0,
})

/* ====== 2. 请求拦截 ====== */
instance.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem('authorization')
    if (token) config.headers.Authorization = `Bearer ${token}`
    return config
  },
  (error) => Promise.reject(error)
)

/* ====== 3. 响应拦截 ====== */
instance.interceptors.response.use(
  (res: AxiosResponse) => {
    if (res.config.responseType == 'blob') {
      return res.data
    }

    // 后端统一返回 { code:0, data:..., msg:'...' }
    const { code, message } = res.data
    const url = res.config.url
    if (
      code === 200 &&
      url?.includes('/auth/login') &&
      res.headers['authorization']
    ) {
      localStorage.setItem(
        'authorization',
        res.headers['authorization'].replace(/^Bearer\s+/i, '')
      )
    }
    if (code != 200) {
      msg.error(message || '系统错误')
    }
    if (code == 401) {
      localStorage.clear()
      router.navigate('/login', { replace: true })
    }
    return res.data // 直接返回业务数据
  },
  async (error: AxiosError) => {
    const { response } = error
    if (response?.status === 401) {
      localStorage.clear()
      router.navigate('/login', { replace: true })
    } else {
      msg.error((response?.data as any)?.msg || '网络异常')
    }
    return { code: 500, message: (response?.data as any)?.msg || '网络异常' }
  }
)

/* ====== 4. 常用方法二次包装 ====== */
export const http = {
  get<T = any>(
    url: string,
    params?: object,
    config?: AxiosRequestConfig
  ): Promise<T> {
    return instance.get(url, { params, ...config })
  },
  post<T = any>(
    url: string,
    data?: object,
    config?: AxiosRequestConfig
  ): Promise<T> {
    return instance.post(url, data, config)
  },
  put<T = any>(
    url: string,
    data?: object,
    config?: AxiosRequestConfig
  ): Promise<T> {
    return instance.put(url, data, config)
  },
  delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
    return instance.delete(url, config)
  },
  upload<T = any>(url: string, file: File, params?: object): Promise<T> {
    const fd = new FormData()
    fd.append('file', file)
    Object.keys(params ?? {}).forEach((k) => fd.append(k, (params as any)[k]))
    return instance.post(url, fd, {
      headers: { 'Content-Type': 'multipart/form-data' },
    })
  },
}

/* ====== 5. 导出实例（高级场景自己用） ====== */
export default instance
